package tt.dz.order.controller;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import tt.dz.order.dao.SysApplicationContextAware;
import tt.dz.order.exception.BusinessException;
import tt.dz.order.pojo.OrderInfo;
import tt.dz.order.pojo.OrderServiceInfo;
import tt.dz.order.pojo.OrderSummaryReport;
import tt.dz.order.service.OrderService;
import tt.dz.order.util.AliPayUtil;
import tt.dz.order.util.AmountUtil;
import tt.dz.order.util.OrderConstant;
import tt.dz.order.util.OrderConstant.AliPayTradeStatus;
import tt.dz.order.util.OrderConstant.CardType;
import tt.dz.order.util.OrderConstant.OrderStatus;
import tt.dz.order.util.WeiXinPayUtilBase;
import tt.dz.order.util.XmlUtil;
import tt.dz.order.util.YouBeiPayUtil;
import tt.dz.order.vo.CardTypeVo;
import tt.dz.order.vo.CreatedOrderVO.ServicePriceVO;
import tt.dz.order.vo.OrderBaseData;
import tt.dz.order.vo.RetVO;
import tt.dz.order.vo.UserPayInfoVO;

/**
 * @Title: 订单系统对用户提供的http控制器接口
 * @author zhoutian
 * @date 2015-11-17
 */
@Controller
public class OrderController {
	private static Logger log = LoggerFactory.getLogger(OrderController.class);
	@Autowired
	private OrderService orderService;

	/**
	 * 服务价格查询
	 * 
	 * @param serviceNo
	 *            服务编号
	 * @param serviceProviderCode
	 *            服务提供商编号
	 * @param buyNum
	 *            购买数量，如预约时间、电量等
	 * @return 价格
	 */
	@RequestMapping(value = "/orderService/servicePriceQuery", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String servicePriceQuery(@RequestBody String orderBaseDatasJSONStr) {
		log.info("服务价格查询controller层,orderBaseDatasJSONStr:", orderBaseDatasJSONStr);
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			List<OrderBaseData> orderBaseDatas = JSON.parseArray(orderBaseDatasJSONStr, OrderBaseData.class);
			List<ServicePriceVO> servicePriceVOList = orderService.servicePriceQuery(orderBaseDatas);
			retVO.setBizData(servicePriceVOList);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("用户正在支付controller层发生异常", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 用户发起支付
	 * 
	 * @param jsonStr
	 *            APP-Server或第三方服务器传过来的JSON字符串
	 */
	@RequestMapping(value = "/orderService/userPaying", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String userPaying(@RequestBody String userPayInfoStr) {
		log.info("用户正在支付controller层,userPayInfoStr:", userPayInfoStr);
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			UserPayInfoVO userPayInfoVO = JSON.parseObject(userPayInfoStr, UserPayInfoVO.class);
			orderService.transUserPaying(userPayInfoVO);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("用户正在支付controller层发生异常", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 有贝先付回调
	 * 
	 * @param jsonStr
	 *            有贝先付回调传递过来的JSON字符串
	 */
	@RequestMapping(value = "/orderService/youbeiPayCallback", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String youbeiPayCallback(@RequestBody String jsonStr) {
		log.info("收到有贝支付回调controller层,jsonStr:", jsonStr);
		try {
			JSONObject jsonObject = JSON.parseObject(jsonStr);
			Map<String, String> params = new HashMap<String, String>();
			params.put("no_order", jsonObject.getString("no_order"));
			params.put("sign_type", jsonObject.getString("sign_type"));
			params.put("sign", jsonObject.getString("sign"));
			params.put("sign_field", jsonObject.getString("sign_field"));
			params.put("dt_order", jsonObject.getString("dt_order"));
			params.put("oid_paybill", jsonObject.getString("oid_paybill"));
			params.put("result_pay", jsonObject.getString("result_pay"));
			params.put("oid_partner", jsonObject.getString("oid_partner"));
			params.put("result_pay", jsonObject.getString("result_pay"));
			params.put("oid_partner", jsonObject.getString("oid_partner"));
			params.put("money_order", jsonObject.getString("money_order"));
			params.put("settle_date", jsonObject.getString("settle_date"));
			params.put("info_order", jsonObject.getString("info_order"));
			if (YouBeiPayUtil.verify(params)) {
				String orderNo = (String) params.get("no_order");
				String money_order = (String) params.get("money_order");
				OrderInfo order = orderService.getOrderByNo(orderNo);
				if (order == null) {
					log.error("有贝支付回调controller层，订单不存在，orderNo：" + orderNo);
					return YouBeiPayUtil.RET_FAIL_JSON;
				}
				if (!AmountUtil.equal(new BigDecimal(money_order), order.getCaculatedTotalPrice())) {
					log.error("有贝支付回调controller层，money_order验证失败：" + orderNo + "、" + money_order);
					return YouBeiPayUtil.RET_FAIL_JSON;
				}
				return orderService.transYouBeiPayCallBack(params);
			} else {
				log.error("有贝支付回调处理controller层验证失败");
				return YouBeiPayUtil.RET_FAIL_JSON;
			}
		} catch (Exception e) {
			log.error("有贝支付回调controller层发生异常", e);
			return YouBeiPayUtil.RET_FAIL_JSON;
		}
	}

	/**
	 * 订单支付宝支付回调
	 * 
	 * @return success/fail
	 */
	@RequestMapping(value = "/orderService/aliPayCallback", produces = "text/html;charset=UTF-8")
	@ResponseBody
	public String aliPayCallback(HttpServletRequest request, HttpServletResponse response) {
		log.info("收到支付宝支付回调，controller层");
		try {
			// 获取支付宝POST过来反馈信息
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String[]> requestParams = request.getParameterMap();
			for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "gbk");
				params.put(name, valueStr);
			}
			log.info("支付宝支付回调参数,params:" + params);
			if (AliPayUtil.verify(params)) {
				log.info("支付宝支付回调，controller层，支付宝请求验证成功");
				// 验证成功
				// 交易状态
				// String trade_status = new
				// String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
				String trade_status = request.getParameter("trade_status");
				// 商户订单号
				String out_trade_no = request.getParameter("out_trade_no");
				// 卖家支付宝用户号
				String seller_id = request.getParameter("seller_id");
				// 交易金额
				String total_fee = request.getParameter("total_fee");
				/*
				 * if(trade_status.equals("TRADE_FINISHED")){
				 * //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
				 * //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				 * } else if (trade_status.equals("TRADE_SUCCESS")){
				 * //付款完成后，支付宝系统发送该交易状态通知
				 * //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				 * }
				 */
				if (trade_status.equals(AliPayTradeStatus.TRADE_SUCCESS.value())
						|| trade_status.equals(AliPayTradeStatus.TRADE_FINISHED.value())) {
					OrderInfo order = orderService.getOrderByNo(out_trade_no);
					if (order == null) {
						log.error("\t支付宝支付回调controller层，订单不存在，orderNo：" + out_trade_no + "\n");
						return AliPayUtil.RET_FAIL_STR;
					}
					log.info("\t订单查找成功[" + out_trade_no + "]~\n");
					if (seller_id.equals(SysApplicationContextAware.getBean(AliPayUtil.class).PARTNER)
							&& AmountUtil.equal(new BigDecimal(total_fee), order.getCaculatedTotalPrice())) {
						log.info("\t开始进行相关信息的业务逻辑属性[seller_id,total_fee]校验成功\n");
						String isSuccess = orderService.transAliPayCallBack(params);
						log.info("\t支付宝支付回调处理服务层结果=" + isSuccess + "\n");
						return isSuccess;
					} else {
						log.info("\t支付宝支付回调controller层，total_fee、seller_id验证失败：" + out_trade_no + "、" + seller_id + "、"
								+ total_fee + "\n");
						return AliPayUtil.RET_FAIL_STR;
					}
				}
				log.info("\t开始进行相关信息的业务逻辑属性[trade_status]校验不成功~\n");
				return AliPayUtil.RET_FAIL_STR;
			} else {
				log.error("\t开始校验回调参数[AliPayUtil.verify]失败\n");
				return AliPayUtil.RET_FAIL_STR;
			}
		} catch (Exception e) {
			log.error("支付宝支付回调controller层，出错", e);
			return AliPayUtil.RET_FAIL_STR;
		}
	}

	/**
	 * 微信支付回调
	 * 
	 * @param xmlStr
	 *            微信支付回调传递过来的xml字符串
	 */
	@RequestMapping(value = "/orderService/weixinPayCallback")
	@ResponseBody
	public String weixinPayCallback(@RequestBody String xmlStr) {
		log.info("收到微信支付回调controller层,xmlStr:"+ xmlStr);
		Map<String, Object> params = null;
		try {
			params = XmlUtil.Xml2Map(xmlStr);
			String appid = params.get("attach").toString();
			if (OrderConstant.BizSystemCode.HuaTiWeiXin.value().equals(appid)||OrderConstant.BizSystemCode.DzWeiXin.value().equals(appid)) {
				String weixinMchKey =WeiXinPayUtilBase.getweiXinPropertieBykey(appid+"Weixin.WeixinMchKey");
				if (WeiXinPayUtilBase.verify(params,weixinMchKey)) {
					String orderNo = (String) params.get("out_trade_no");
					String total_fee = (String) params.get("total_fee");
					OrderInfo order = orderService.getOrderByNo(orderNo);
					if (order == null) {
						log.error("微信支付回调controller层，订单不存在，orderNo：" + orderNo);
						return WeiXinPayUtilBase.RET_FAIL_XML;
					}
					if(OrderStatus.payedDone.value() ==order.getStatus()){
						log.error("微信支付回调controller层，已经被支付，orderNo：" + orderNo);
						return WeiXinPayUtilBase.RET_SUCCESS_XML;
					}
					BigDecimal price = AmountUtil.multiply(order.getCaculatedTotalPrice(), new BigDecimal("100"));
					price = AmountUtil.scale(price, 0);
					if (!AmountUtil.equal(new BigDecimal(total_fee), price)) {
						log.error("微信支付回调controller层，total_fee验证失败：" + orderNo + "、" + total_fee);
						return WeiXinPayUtilBase.RET_FAIL_XML;
					}
					return orderService.transWeiXinPayCallBack(params);
				} else {
					log.error("微信支付回调处理controller层验证失败");
					return WeiXinPayUtilBase.RET_FAIL_XML;
				}
			} else {
				log.error("当前不支持业务系统编码为:" + appid + "的微信回调");
				return WeiXinPayUtilBase.RET_FAIL_XML;
			}
		} catch (Exception e) {
			log.error("微信支付回调处理controller层发生异常", e);
			return WeiXinPayUtilBase.RET_FAIL_XML;
		}
	}

	/**
	 * 支付宝充值到现金卡的金额回调
	 * 
	 * @return success/fail
	 */
	@RequestMapping(value = "/orderService/aliPayRechargeCashCardCallback", produces = "text/html;charset=UTF-8")
	@ResponseBody
	public String aliPayRechargeCashCardCallback(HttpServletRequest request, HttpServletResponse response) {
		log.info("收到支付宝充值到现金卡的金额回调，controller层");
		try {
			// 获取支付宝POST过来反馈信息
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String[]> requestParams = request.getParameterMap();
			for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "gbk");
				params.put(name, valueStr);
			}
			log.info("支付宝充值到现金卡的金额回调参数,params:" + params);
			if (AliPayUtil.verify(params)) {
				log.info("支付宝充值到现金卡的金额回调，controller层，支付宝请求验证成功");
				// 验证成功
				// 交易状态
				// String trade_status = new
				// String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
				String trade_status = request.getParameter("trade_status");
				// 商户订单号
				String out_trade_no = request.getParameter("out_trade_no");
				// 卖家支付宝用户号
				String seller_id = request.getParameter("seller_id");
				// 交易金额
				String total_fee = request.getParameter("total_fee");
				/*
				 * if(trade_status.equals("TRADE_FINISHED")){
				 * //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
				 * //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				 * } else if (trade_status.equals("TRADE_SUCCESS")){
				 * //付款完成后，支付宝系统发送该交易状态通知
				 * //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				 * }
				 */
				if (trade_status.equals(AliPayTradeStatus.TRADE_SUCCESS.value())
						|| trade_status.equals(AliPayTradeStatus.TRADE_FINISHED.value())) {
					OrderInfo order = orderService.getOrderByNo(out_trade_no);
					if (order == null) {
						log.error("\t支付宝充值到现金卡的金额回调controller层，订单不存在，orderNo：" + out_trade_no + "\n");
						return AliPayUtil.RET_FAIL_STR;
					}
					log.info("\t支付宝充值到现金卡的金额回调,订单查找成功[" + out_trade_no + "]，订单金额[" + order.getCaculatedTotalPrice()
							+ "],充现金金额[" + total_fee + "]~\n");
					if (seller_id.equals(SysApplicationContextAware.getBean(AliPayUtil.class).PARTNER)) {
						log.info("\t开始进行相关信息的业务逻辑属性[seller_id]校验成功\n");
						String isSuccess = orderService.transAliPayRechargeCashCardCallback(params);
						log.info("\t支付宝充值到现金卡的金额回调处理服务层结果=" + isSuccess + "\n");
						return isSuccess;
					} else {
						log.info("\t支付宝充值到现金卡的金额回调controller层，seller_id验证失败：" + out_trade_no + "、" + seller_id + "、"
								+ total_fee + "、" + order.getCaculatedTotalPrice() + "\n");
						return AliPayUtil.RET_FAIL_STR;
					}
				}
				log.info("\t开始进行相关信息的业务逻辑属性[trade_status]校验不成功~\n");
				return AliPayUtil.RET_FAIL_STR;
			} else {
				log.error("\t开始校验回调参数[AliPayUtil.verify]失败\n");
				return AliPayUtil.RET_FAIL_STR;
			}
		} catch (Exception e) {
			log.error("支付宝充值到现金卡的金额回调controller层，出错", e);
			return AliPayUtil.RET_FAIL_STR;
		}
	}

	/**
	 * 用户取消充电预约
	 */
	@RequestMapping(value = "/osrderService/userCancelChargeAppointment", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String userCancelChargeAppointment(@RequestParam(value = "userId", required = true) String userId,
			@RequestParam(value = "orderNo", required = true) String orderNo) {
		log.info("用户取消充电预约controller层,userId,orderNo:", userId + "," + orderNo);
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			retVO = orderService.transUserCancelChargeAppointment(userId, orderNo);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("用户取消充电预约controller层发生异常", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 根据订单号查询生成的订单信息
	 */
	@RequestMapping(value = "/orderService/getCreatedOrderInfo", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String getCreatedOrderVO(@RequestParam(value = "orderNo", required = true) String orderNo) {
		log.info("根据订单号查询生成的订单信息controller层,orderNo:", orderNo);
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			return orderService.getCreatedOrderVO(orderNo);
		} catch (Exception e) {
			log.error("根据订单号查询生成的订单信息controller层发生异常", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 服务列表查询for APP
	 */
	@RequestMapping(value = "/orderService/listOrderServiceInfo", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String listOrderServiceInfo() {
		log.info("服务列表查询controller层");
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			List<OrderServiceInfo> serviceInfoList = orderService.listOrderServiceInfo();
			retVO.setBizData(serviceInfoList);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("服务列表查询controller层", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 查询当前系统支持的卡类型
	 */
	@RequestMapping(value = "/orderService/queryCardType", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String queryCardType() {
		log.info("卡类型查询controller层");
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {

			List<CardTypeVo> cardTypeVoList = new ArrayList<>();
			CardType[] cardTypes = CardType.values();
			for (CardType cardType : cardTypes) {
				CardTypeVo cardTypeVo = new CardTypeVo();
				cardTypeVo.setCardTypeName(cardType.getDesc());
				cardTypeVo.setCardTypeNo(cardType.value());
				cardTypeVoList.add(cardTypeVo);
			}
			retVO.setBizData(cardTypeVoList);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("卡类型查询controller层", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}

	/**
	 * 汇总报表
	 */
	@RequestMapping(value = "/orderService/summaryReport", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String summaryReport(HttpServletRequest request) {
		log.info("汇总报表controller层");
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			OrderSummaryReport.createSummary();
		} catch (BusinessException e) {
			log.error("汇总报表controller层", e);
			retVO.setRetCode(RetVO.FailCode);
			retVO.setErrorMsg(e.getMessage());
			return retVO.toJSONString();
		}
		return retVO.toJSONString();
	}
	/**
	 * 查询汇总报表信息
	 */
	@RequestMapping(value = "/orderService/queryOrderSummaryReport", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String queryOrderSummaryReport(HttpServletRequest request) {
		log.info("汇总报表查询controller层");
		RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);
		try {
			String cartTyep = request.getParameter("cardTypeNo");
			String serverNo = request.getParameter("serviceNo");
			String startTime = request.getParameter("startTime");
			String endTime = request.getParameter("endTime");
			List<OrderSummaryReport> list;

			list = OrderSummaryReport.queryOrderSummaryReport(cartTyep, serverNo, startTime, endTime);
			Collections.sort(list, new Comparator<OrderSummaryReport>() {

				@Override
				public int compare(OrderSummaryReport o1, OrderSummaryReport o2) {
					Date d1;
					SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
					try {
						d1 = dateFormat.parse(o1.getDate_m());
						Date d2 = dateFormat.parse(o2.getDate_m());
						if (d1.before(d2)) {
							return -11;

						} else if (d1.after(d2)) {

							return 1;
						} else {

							return 0;
						}
					} catch (ParseException e) {
						log.error("时间格式化错误" + e);
					}
					return 0;
				}
			});
			;
			retVO.setBizData(list);
			return retVO.toJSONString();
		} catch (Exception e) {
			log.error("汇总报表查询controller层", e);
			retVO.setRetCode(RetVO.FailCode);
			return retVO.toJSONString();
		}
	}
}
